package blank;

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.apache.log4j.Logger;

/**
 * Cache is singleton, serializes itself with complete underlying graph.
 * 
 * @author Marcis
 * 
 */
public class Cache implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6283983466154497301L;

	private static final Logger log = Logger.getLogger(Cache.class);

	public static final File cacheFile = new File("cache.bin");

	private static Cache instance = new Cache();

	private Cache() {
		// private constructor
	}

	public static Cache getInstance() {
		return instance;
	}

	/**
	 * Saves analysis to filesystem for faster future analysis.
	 */
	public void saveToDisk() {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(cacheFile, false));
			oos.writeObject(this);
			oos.close();
		} catch (IOException e) {
			log.error("Cannot save cache file " + cacheFile + ". " +
			e.getMessage());
		}
	}

	/**
	 * for work with cache file.
	 * 
	 * @return cache file from filesystem
	 */
	public static Cache loadFromDisk() {
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream(cacheFile));
			Object object = null;
			while ((object = ois.readObject()) != null) {
				if (object instanceof Cache) {
					return (Cache) object;
				} else {
					log.warn("V souboru nema byt nic jineho nez CacheJars objekt!");
				}
			}
		} catch (EOFException e) {
			log.error("End of bin file reached.", e);
			return null;
		} catch (FileNotFoundException e) {
			log.error("Cache file not found.", e);
			return null;
		} catch (IOException e) {
			log.error("I/O exc. while loading cache file.", e);
			return null;
		} catch (ClassNotFoundException e) {
			log.error("Class existing in file not found in app-classpath.", e);
			return null;
		} finally {
			try {
				ois.close();
			} catch (IOException e) {
				log.error("Can not close cache file!", e);
			}
		}
		return null;
	}

}
